import React, { useState, useEffect, useRef } from "react";
import { connect, useDispatch, history } from "umi";
import { Table, Input, Form, Typography, Popconfirm, Select } from "antd";
const TablePage = (props) => {
  const {
    loading = false,
    columns = [],
    scroll = {
      y: 560,
    },
    data = [],
    tableDataChange,
  } = props;

  const [form] = Form.useForm();
  // 表格数据
  const [tableData, setTableData] = useState(data);

  // 当前行的key
  const [editingKey, setEditingKey] = useState("");

  // 判断是否一致
  const isEditing = (record) => record.key == editingKey;

  // 双击触发显示表单
  const doubleClick = (record, event) => {
    form.setFieldsValue({
      ...record,
    });
    setEditingKey(record.key);
  };

  // 初始化数据 检查数据
  const initData = () => {
    if (!Array.isArray(data)) {
      throw new Error("XH-table组件警告:data属性数据类型错误 -> 应为Array 传入却是" + typeof data);
    }
    setTableData(data);
    return data;
  };

  // 检查 columns 数据是否正确 并且判断是否需要提供表单组件
  const initColumns = () => {
    if (!Array.isArray(columns)) {
      return [
        {
          title: `XH-table组件警告:columns属性数据类型错误 -> 应为Array 传入却是 ${typeof columns}`,
        },
      ];
    }
    //  判断返回不同的数据 表单还是数据
    let arr = columns.map((col) => {
      if (!isEditing) {
        // 原封不动
        return col;
      }
      // 表单数据
      return {
        ...col,
        onCell: (record) => ({
          record,
          dataIndex: col.dataIndex,
          title: col.title,
          editing: isEditing(record),
          inputType: col.inputType,
          disabled: col.disabled || false,
        }),
      };
    });

    // 数据最后添加操作 用于触发表单填写
    arr.push({
      title: "操作",
      dataIndex: "X",
      render: (_, record) => {
        const editable = isEditing(record);
        return editable ? (
          <span>
            <Typography.Link
              onClick={() => save(record.key)}
              style={{
                marginRight: 8,
              }}
            >
              保存
            </Typography.Link>
            <Popconfirm title="数据未保存,是否取消?" onConfirm={cancel}>
              <a>取消</a>
            </Popconfirm>
          </span>
        ) : (
          <Typography.Link disabled={editingKey !== ""} onClick={() => doubleClick(record)}>
            修改数据
          </Typography.Link>
        );
      },
    });
    return arr;
  };

  // 判断需要的组件
  const getNode = ({
    editing,
    dataIndex,
    title,
    inputType,
    record,
    index,
    children,
    option,
    disabled,
    ...restProps
  }) => {
    if (inputType === "number") {
      return <InputNumber />;
    } else if (inputType === "input") {
      return <Input placeholder={`请填写${title}`} />;
    } else if (inputType === "select") {
      return (
        <Select
          showSearch
          placeholder={`请选择${title}`}
          filterOption={(input, option) =>
            (option?.label ?? "").toLowerCase().includes(input.toLowerCase())
          }
          options={option || []}
        />
      );
    } else if (disabled) {
      return <div>{record[dataIndex] || "--"}</div>;
    } else {
      return <Input placeholder={`请填写${title}`} />;
    }
  };

  // 提供编辑组件 带出参数为 columns 属性所有值 也就是说columns属性传入什么就带出什么
  // editing 是当前文件的判断 是否显示表单
  const EditableCell = ({
    editing,
    dataIndex,
    title,
    inputType,
    record,
    index,
    children,
    rules,
    disabled,
    ...restProps
  }) => {
    return (
      <td {...restProps}>
        {editing ? (
          <Form.Item
            name={dataIndex}
            style={{
              margin: 0,
            }}
            rules={
              rules || [
                {
                  required: true,
                  message: `请填写${title}!`,
                },
              ]
            }
          >
            {/* 获取组件 */}
            {getNode({
              editing,
              dataIndex,
              title,
              inputType,
              record,
              index,
              children,
              disabled,
              ...restProps,
            })}
          </Form.Item>
        ) : (
          children
        )}
      </td>
    );
  };

  // 取消
  const cancel = () => {
    setEditingKey("");
  };

  // 保存
  const save = async (key) => {
    try {
      const row = await form.validateFields();
      const newData = [...data];
      const index = newData.findIndex((item) => key === item.key);
      if (index > -1) {
        const item = newData[index];
        newData.splice(index, 1, {
          ...item,
          ...row,
        });
        console.log(newData);
        tableDataChange(newData);
        setEditingKey("");
      } else {
        newData.push(row);
        tableDataChange(newData);
        setEditingKey("");
      }
    } catch (errInfo) {
      console.log("Validate Failed:", errInfo);
    }
  };
  useEffect(() => {
    initData();
  }, []);
  return (
    <Form form={form} component={false}>
      <Table
        components={{
          body: {
            cell: EditableCell,
          },
        }}
        onRow={(record) => {
          return {
            onDoubleClick: (event) => doubleClick(record, event),
          };
        }}
        loading={loading}
        columns={initColumns()}
        rowSelection={null}
        dataSource={data}
        scroll={scroll}
      />
    </Form>
  );
};
export default connect((state) => ({ user: state.user }))(TablePage);
